// -----------------------------------------------------------------------
//  <copyright file="ISettingStore.cs" company="LiuliuSoft">
//      Copyright (c) 2022-2024 DaprPlus. All rights reserved.
//  </copyright>
//  <site>https://www.dapr.plus</site>
//  <last-editor>郭明锋</last-editor>
//  <last-date>2024-04-15 21:02</last-date>
// -----------------------------------------------------------------------

using DaprPlus.Settings.Domain.Entities;
using DaprPlus.Settings.Domain.Dtos;
using DaprPlus.Domain;


namespace DaprPlus.Settings.Domain.Services;

/// <summary>
/// 定义设置信息存储接口
/// 支持强类型设置类的管理，每个设置类的公开属性代表一个设置项
/// </summary>
public interface ISettingStore
{
    /// <summary>
    /// 根据设置类型名称获取强类型设置对象
    /// 如果数据库中没有数据，则从强类型类创建默认值
    /// </summary>
    /// <typeparam name="TSetting">设置类型，必须实现ISetting接口</typeparam>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>强类型设置对象</returns>
    Task<TSetting> GetSettingAsync<TSetting>(CancellationToken cancellationToken = default) where TSetting : class, ISetting, new();

    /// <summary>
    /// 根据设置类型名称获取设置定义（可能返回null）
    /// </summary>
    /// <param name="typeName">设置类型名称</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>设置定义，如果不存在则返回null</returns>
    Task<SettingDefinitionOutDto?> GetSettingDefinitionOrNullAsync(string typeName, CancellationToken cancellationToken = default);

    /// <summary>
    /// 根据设置类型名称获取设置定义，如果不存在则创建
    /// 如果数据库中没有数据，则从设置类型类创建默认值
    /// </summary>
    /// <param name="typeName">设置类型名称</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>设置定义，如果不存在则从设置类型创建</returns>
    Task<SettingDefinitionOutDto> GetOrCreateSettingDefinitionAsync(string typeName, CancellationToken cancellationToken = default);

    /// <summary>
    /// 保存设置定义到数据库
    /// </summary>
    /// <param name="settingDto">设置定义对象</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>保存结果</returns>
    Task<ApiResult> SaveSettingAsync(SettingDefinitionInDto settingDto, CancellationToken cancellationToken = default);

    /// <summary>
    /// 保存单个设置项
    /// </summary>
    /// <param name="typeName">设置类型名称</param>
    /// <param name="settingItem">设置项</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>保存结果</returns>
    Task<ApiResult> SaveSettingItemAsync(string typeName, SettingItemInDto settingItem, CancellationToken cancellationToken = default);

    /// <summary>
    /// 根据设置类型名称删除所有相关设置
    /// </summary>
    /// <param name="typeName">设置类型名称</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>删除结果</returns>
    Task<ApiResult> DeleteSettingsAsync(string typeName, CancellationToken cancellationToken = default);

    /// <summary>
    /// 根据设置类型名称和属性名删除单个设置项
    /// </summary>
    /// <param name="typeName">设置类型名称</param>
    /// <param name="propertyName">属性名</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>删除结果</returns>
    Task<ApiResult> DeleteSettingItemAsync(string typeName, string propertyName, CancellationToken cancellationToken = default);

    /// <summary>
    /// 重置指定类型的设置项到类型设定的默认值
    /// </summary>
    /// <param name="typeName">设置类型名称</param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    Task<ApiResult<SettingDefinitionOutDto>> ResetSettingAsync(string typeName, CancellationToken cancellationToken);
}
